home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Information / CSMP Digest / volume 1 / csmp-v1-179.txt < prev    next >
Text File  |  1992-12-31  |  43KB  |  1,262 lines

  1. C.S.M.P. Digest             Fri, 09 Oct 92       Volume 1 : Issue 179
  2.  
  3. Today's Topics:
  4.  
  5.     ColorTables:  misc. tidbits and code
  6.     Keeping the cursor visible
  7.     Zbasic+System 6/7 Speed
  8.     Function missing from MPW C library?
  9.  
  10.  
  11.  
  12. The Comp.Sys.Mac.Programmer Digest is moderated by Michael A. Kelly.
  13.  
  14. The digest is a collection of article threads from the internet newsgroup
  15. comp.sys.mac.programmer.  It is designed for people who read c.s.m.p. semi-
  16. regularly and want an archive of the discussions.  If you don't know what a
  17. newsgroup is, you probably don't have access to it.  Ask your systems
  18. administrator(s) for details.  (This means you can't post questions to the
  19. digest.)
  20.  
  21. Each issue of the digest contains one or more sets of articles (called
  22. threads), with each set corresponding to a 'discussion' of a particular
  23. subject.  The articles are not edited; all articles included in this digest
  24. are in their original posted form (as received by our news server at
  25. cs.uoregon.edu).  Article threads are not added to the digest until the last
  26. article added to the thread is at least one month old (this is to ensure that
  27. the thread is dead before adding it to the digest).  Article threads that
  28. consist of only one message are generally not included in the digest.
  29.  
  30. The entire digest is available for anonymous ftp from ftp.cs.uoregon.edu
  31. [128.223.8.8] in the directory /pub/mac/csmp-digest.  Be sure to read the
  32. file /pub/mac/csmp-digest/README before downloading any files.  The most
  33. recent issues are available from sumex-aim.stanford.edu [36.44.0.6] in the
  34. directory /info-mac/digest/csmp.  If you don't have ftp capability, the sumex
  35. archive has a mail server; send a message with the text '$MACarch help' (no
  36. quotes) to LISTSERV@ricevm1.rice.edu for more information.
  37.  
  38. The digest is also available via email.  Just send a note saying that you
  39. want to be on the digest mailing list to mkelly@cs.uoregon.edu, and you will
  40. automatically receive each new issue as it is created.  Sorry, back issues
  41. are not available through the mailing list.
  42.  
  43. Send administrative mail to mkelly@cs.uoregon.edu.
  44.  
  45.  
  46. -------------------------------------------------------
  47.  
  48. From: k044477@hobbes.kzoo.edu (Jamie R. McCarthy)
  49. Subject: ColorTables:  misc. tidbits and code
  50. Date: 3 Sep 92 16:32:09 GMT
  51. Organization: Kalamazoo College
  52.  
  53. This article starts off with some AppleLink mail from Forrest Tanaka,
  54. telling you more than you ever wanted to know about color tables, and
  55. ends with a fair amount of ANSI C source code for manipulating them.
  56. This is, in short, a hodgepodge of answers and solutions.  If you're
  57. a little confused about color graphics on the Mac (who isn't?!),
  58. well, who knows--this may clear up something for you.
  59.  
  60. Please note that the code is copyrighted and may not be used directly
  61. in a for-profit program.  That's 'cause my company paid me to write
  62. it and it's not fair for you to steal it.  Sorry.  If you want to use
  63. it, fix a bug for me.  (There must be at least one.)  Otherwise,
  64. you're free to use it directly in private or free programs, and to
  65. write your own code based on mine.
  66.  
  67. Comments, especially on the source code, are heartily welcomed.
  68.  
  69.  Jamie McCarthy      Internet: k044477@kzoo.edu      AppleLink: j.mccarthy
  70.  
  71.  
  72.  
  73.  
  74.  
  75. Item    5744291                        10-July-92        16:02PDT
  76. From:   DEVSUPPORTJ                    Developer Support Center
  77. To:     J.MCCARTHYJ                    MCE-Lawrence Prod, J McCarthy
  78. Sub:    RE-ColorTable code-level Q's
  79.  
  80. July 10, 1992
  81.  
  82. Hi Jamie
  83.  
  84. I received your questions about color tables, and since there are
  85. several questions, IUll put the text of your question in a narrow
  86. paragraph and respond to each one in the normal paragraphs
  87. afterwards.  
  88.  
  89.         When drawing offscreen, every CQD routine will handle both
  90.         indexed and sequential tables properly;  in addition,
  91.         CopyBits will handle a "paletted" table for its source
  92.         PixMap.  Right?
  93.  
  94. Yes.  If the source PixMap to CopyBits is paletted and the destination
  95. is a window with a palette, then CopyBits uses the value field of
  96. each ColorSpec record as a palette index for each pixel, which is of
  97. course the whole idea behind paletted color tables.  If the
  98. destination is anything else, then bit 14 of ctFlags is ignored and
  99. the color table is treated as either indexed or sequential depending
  100. on the value of bit 15.  Bit 14 is also ignored when its color
  101. tableUs PixMap is used as the destination to CopyBits.  
  102.  
  103.         IM V-136, contradictorially, says "The ctFlags field is
  104.         significant for gDevices only," and "Color tables that are
  105.         part of [non-GDevice] pixMaps have this bit clear."  What
  106.         this means is, "Clear your own ctFlags, use indexed tables,
  107.         and don't mess with a GDevice's ctFlags."  Right?
  108.  
  109. Inside Macintosh is simply wrong on this point, though it was the
  110. popular belief for quite a while.  The truth is that QuickDraw reads
  111. ctFlags regardless of whether the color tableUs PixMap belongs to a
  112. GDevice, a GWorld, or is one that you created.  If you create your
  113. own PixMap and want to use a sequential color table, set this bit. 
  114. If you want an indexed color table, clear this bit. QuickDraw will
  115. read this bit and do the right thing.  I personally always make
  116. indexed color tables because I happen to be more comfortable with
  117. them, but you can make a sequential one if you want, and QuickDraw
  118. will have no problems with it.
  119.  
  120. ItUs true that all screen GDevices have color tables which are
  121. sequential, but that doesnUt mean that all GDevices must have
  122. sequential color tables.  If you make a GDevice yourself, say for
  123. off-screen drawing, then you can have either a sequential or indexed
  124. color table.  QuickDraw will read the most significant bit of ctFlags
  125. and act accordingly.
  126.  
  127.  
  128.         I understand that video drivers expect sequential tables.
  129.         But, is there anything at all wrong with mixing and
  130.         matching sequential and indexed tables when they don't
  131.         belong to GDevices?
  132.  
  133. No, no problem at all.  In fact, as I mentioned, you can mix and match
  134. even if a color table belongs to a GDevice.  The only thing you canUt
  135. do is change the color table of a screenUs GDevice directly.
  136.  
  137.  
  138.         Must an indexed table be sorted?
  139.  
  140. No.  You can arrange an indexed color table in random order if you
  141. want to, as long as you set the value field of each the color
  142. specification records to the pixel value that you want for each
  143. color.  For example, these two four-entry color tables are identical
  144. assuming ctFlags is zero:
  145.  
  146. Entry  value rgb          Entry  value rgb
  147. 0      0     white        0      2     mauve
  148. 1      1     green        1      1     green
  149. 2      2     mauve        2      3     black
  150. 3      3     black        3      0     white
  151.  
  152.  
  153.         IM V-138 says "...when the Color2Index routine is called,
  154.         it can find the best match to the full 48-bit resolution
  155.         available in a colorSpec."  Really?  Even if the inverse
  156.         table's only 3 bits and my color table consists of (for
  157.         example) a 256-shade gradation from black to white?
  158.         Doesn't that require appending a whole lot of information
  159.         after the inverse table?
  160.  
  161. Inside Macintosh is right, and so are you.  If you have two colors
  162. that differ only in the least significant bit of each of their
  163. components, Color2Index will be able to tell the difference.  The
  164. inverse-table look-up is just the first step; itUs a coarse
  165. estimation of what the final pixel value is. At the end of the
  166. inverse table is a linked list of colors, called the hidden-color
  167. list.  After the inverse-table look-up is complete, this coarse
  168. estimate is fine-tuned using the hidden-color list so that
  169. Color2Index can tell the difference between two colors down to the
  170. last bit.  Color QuickDraw doesnUt always use the hidden-color list
  171. though.  If you use the arithmetic modes with CopyBits, only the
  172. coarse, inverse-table look-up is done.  If you use dithering with
  173. CopyBits, the hidden-color list isnUt used either.
  174.  
  175.  
  176.         What will happen if you ask CQD to manipulate a table whose
  177.         top two ctFlags bits are 11?  (Just out of curiosity.)
  178.  
  179. IUve done this, and itUs fine.  If the PixMap that owns this color
  180. table is used as a source to CopyBits and if the destination is a
  181. window with a palette, this PixMap is treated as a paletted color
  182. table.  If the destination is a window without a palette or a PixMap
  183. thatUs not associated with a window at all, the color table is
  184. treated as a sequential color table.  If the PixMap is used as the
  185. destination to CopyBits, then itUs just treated as a sequential color
  186. table.  Think of it this way: bit 14 has an effect if the color table
  187. belongs to the source PixMap to CopyBits and a window with a palette
  188. is the destination.  In any other case, bit 14 is ignored and bit 15
  189. tells QuickDraw what to do.
  190.  
  191.  
  192. Well, I hope that covers everything.  If you need any clarifications
  193. or any more help, just let me know!
  194.  
  195. - -- Forrest
  196.  
  197.  
  198.  
  199.  
  200.  
  201. /*
  202.  * ColorTableUtils.h
  203.  *
  204.  * Copyright ) 1992 by Lawrence Productions, Inc.  All Rights Reserved.
  205.  *
  206.  * This code may not be used in any for-profit program without the
  207.  * written permission of Lawrence Productions, Inc.
  208.  *
  209.  */
  210.  
  211.  
  212.  
  213. /********************************/
  214.  
  215. #pragma once
  216.  
  217. /********************************/
  218.  
  219.    /*
  220.     * Note that the values of these three constants happen to equal the
  221.     * top two bits of the ctFlags field.  The macro for getColorTableMode()
  222.     * is the only thing that depends on this fact.
  223.     */
  224.    
  225. enum {
  226.    kIndexedColorTable = 0x00,
  227.    kPalettedColorTable = 0x01,
  228.    kSequentialColorTable = 0x02
  229. } ;
  230.  
  231. /********************************/
  232.  
  233.    /*
  234.     * Determine the mode of a color table.
  235.     */
  236.    
  237. short getColorTableMode(CTabPtr theTablePtr);
  238. #define getColorTableMode(theTablePtr) ( \
  239.    ((unsigned short)(theTablePtr)->ctFlags) >> 14 )
  240. #define colorTableIsIndexed(theTablePtr) \
  241.    (getColorTableMode(theTablePtr) == kIndexedColorTable)
  242. #define colorTableIsPaletted(theTablePtr) \
  243.    (getColorTableMode(theTablePtr) == kPalettedColorTable)
  244. #define colorTableIsSequential(theTablePtr) \
  245.    (getColorTableMode(theTablePtr) == kSequentialColorTable)
  246.  
  247.  
  248.    /*
  249.     * Determine whether a color table is sorted.  Naturally, it's designed
  250.     * for indexed tables, but works (trivially) with sequential and
  251.     * paletted tables too.
  252.     */
  253.    
  254. Boolean colorTableIsSorted(CTabPtr theTable);
  255. #define assertColorTableIsSorted(theTable) ASSERT(colorTableIsSorted(theTable));
  256.  
  257.  
  258.    /*
  259.     * Find an entry's offset in a color table.  Naturally, it's designed
  260.     * for indexed tables, but works (trivially) on sequential tables too.
  261.     * Paletted tables may have none or several entries that point to a
  262.     * particular palette entry, and this routine will not attempt to
  263.     * search them, returning kNoEntryFound instead.
  264.     * 
  265.     * For all tables, the output is the index into the ctTable field.
  266.     */
  267.    
  268. #define kNoEntryFound (-1)
  269. short findEntryInSortedTable(CTabPtr theTable, short wEntry);
  270.  
  271.  
  272.    /*
  273.     * Add an entry to a color table.  Returns TRUE if the entry was
  274.     * actually added (i.e. if the table's size went up), and FALSE if
  275.     * the entry wasn't added.  The entry number is of course in the
  276.     * value field.
  277.     *
  278.     * For this one, the table really _does_ have to be indexed.
  279.     */
  280.    
  281. Boolean addEntryToSortedIndexedTable(CTabHandle theIndexedTable, ColorSpec *theColorSpec);
  282.  
  283.  
  284.    /*
  285.     * Convert color storage modes back 'n' forth.  These allocate memory
  286.     * and don't alter the original table.
  287.     *
  288.     * You can't switch to or from a paletted color table without knowing
  289.     * what the palette is, so no routines are provided for that.
  290.     */
  291.    
  292. CTabHandle makeIndexedFromSequential(CTabHandle theSequentialTable);
  293. CTabHandle makeSequentialFromSortedIndexed(CTabHandle theIndexedTable, RGBColor *fillColor);
  294.  
  295.  
  296.    /*
  297.     * Sort a table's entries.  Does nothing if the table is sequential
  298.     * or paletted.
  299.     */
  300.    
  301. void sortIndexedTable(CTabHandle theTable);
  302.  
  303.  
  304.    /*
  305.     * Compare two tables, even if they use different modes.  Paletted
  306.     * tables can't be compared to anything, and so always return FALSE.
  307.     * If both tables are indexed, they must both be sorted.
  308.     */
  309.    
  310. Boolean colorTablesAreEquivalent(CTabHandle table1, CTabHandle table2, RGBColor *fillColor);
  311.  
  312.  
  313.    /*
  314.     * Functions to manipulate the number of entries of a color table.
  315.     * The "get" function is simple, so it comes with a macro.  The
  316.     * others alter the ctSize field and resize the handle;  "set"
  317.     * sets the number of entries directly, while "change" adds or
  318.     * subtracts from the current number of entries.  If the table's
  319.     * size changes, it (and memory) may be moved, even if it's
  320.     * locked.  If the table is lengthened, the new entries contain
  321.     * garbage.
  322.     */
  323.    
  324. short getNCTEntries(CTabPtr theTable);
  325. #define getNCTEntries(theTable) ((theTable)->ctSize+1)
  326. void setNCTEntries(CTabHandle theTable, short nEntries);
  327. void changeNCTEntries(CTabHandle theTable, short nEntries);
  328.  
  329.  
  330.    /*
  331.     * Quickie macros to convert a table's depth to the maximum number of
  332.     * entries, and to convert a number of entries to a minimum depth.
  333.     *
  334.     * The function prototypes are only there to do a little parameter
  335.     * type-checking;  since the macros do their conversion in place,
  336.     * the functions wouldn't actually do anything if you were to call
  337.     * them.  (And if they took pointers instead of doing the work in
  338.     * place, you couldn't use register variables, ick.)  If the functions
  339.     * ever actually _do_ get called, they pop into the debugger with
  340.     * an appropriate message.
  341.     */
  342.  
  343. void convertDepthToMaxNEntries(short d, short n);  
  344. #define convertDepthToMaxNEntries(d,n)                \
  345.    {  short ___depth=(d);                             \
  346.       for ((n)=1; ___depth>=1; --___depth)            \
  347.          (n) <<= 1;                    }
  348.  
  349. void convertNEntriesToMinDepth(short n, short d);
  350. #define convertNEntriesToMinDepth(n,d)                \
  351.    {  short ___nEntries=(n);                          \
  352.       for ((d)=0; ___nEntries>1; ___nEntries>>=1)     \
  353.          ++(d);                        }
  354.  
  355.  
  356.  
  357.  
  358.  
  359. /*
  360.  * ColorTableUtils.c
  361.  *
  362.  * Copyright ) 1992 by Lawrence Productions, Inc.  All Rights Reserved.
  363.  *
  364.  * This code may not be used in any for-profit program without the
  365.  * written permission of Lawrence Productions, Inc.
  366.  *
  367.  */
  368.  
  369.  
  370.  
  371. /********************************/
  372.  
  373. #include "ColorTableUtils.h"
  374.  
  375. /********************************/
  376.  
  377.    /*
  378.     * You'll need to put qsort.c in your project.
  379.     */
  380. #include <stdlib.h>
  381.  
  382. /********************************/
  383.  
  384.    /*
  385.     * The only thing used from JamieUtilities.c is "jmemcmp()," which is
  386.     * just a clone of memcmp().  (I save 100 bytes of object code by
  387.     * taking it out of mem.c, because memcmp() is the only function in
  388.     * there that I would ever use.  I guess I'm a fanatic.)  Anyway, if
  389.     * you don't have JamieUtilities, just #include <string.h>, drop mem.c
  390.     * in your project, and change "jmemcmp" to "memcmp".
  391.     */
  392. #include <JamieUtilities.h>
  393.  
  394. /********************************/
  395.  
  396.  
  397.  
  398. short (getColorTableMode)(CTabPtr theTable)
  399. {
  400.    ASSERT(theTable != NULL);
  401.    
  402.    switch ( ((unsigned short) (theTable)->ctFlags) >> 14 ) {
  403.       
  404.       case 0x00:     return kIndexedColorTable;       break;
  405.       case 0x01:     return kPalettedColorTable;      break;
  406.       case 0x02:     return kSequentialColorTable;    break;
  407.       default:       ASSERT(0);     return -1;        break;
  408.       
  409.    }
  410. }
  411.  
  412.  
  413.  
  414. Boolean colorTableIsSorted(CTabPtr theTable)
  415. {
  416.    register ColorSpec *theCTTable;
  417.    register short cPosition, nEntriesMinusOne, lastEntry;
  418.    
  419.    ASSERT(theTable != NULL);
  420.    
  421.    if (!colorTableIsIndexed(theTable)) {
  422.       return TRUE;
  423.    }
  424.    
  425.    theCTTable = &theTable->ctTable[0];
  426.    nEntriesMinusOne = theTable->ctSize;
  427.    cPosition = 0;
  428.    lastEntry = -1;
  429.    for (cPosition = 0; cPosition <= nEntriesMinusOne; ++cPosition) {
  430.       
  431.       register short thisEntry;
  432.       
  433.       if ( (thisEntry=theCTTable[cPosition].value) < lastEntry) {
  434.          return FALSE;
  435.       } else {
  436.          lastEntry = thisEntry;
  437.       }
  438.       
  439.    }
  440.    
  441.    return TRUE;
  442. }
  443.  
  444.  
  445.  
  446.       /*
  447.        * Returns TRUE iff the entry was found.  If the entry was not found,
  448.        * it returns the position where it should be inserted.
  449.        */
  450.       
  451.    Boolean engineFindEntryInSortedTable(CTabPtr tablePtr, register short wEntry, short *thePosition);
  452.    Boolean engineFindEntryInSortedTable(CTabPtr tablePtr, register short wEntry, short *thePosition)
  453.    {
  454.          /*
  455.           * I'm 99.9% sure this code will find an existing entry, but only
  456.           * 80% sure that it'll return the proper position for a nonexisting
  457.           * one, the proper position being the entry to the right.  I suppose
  458.           * I should test it rigorously one of these days...
  459.           */
  460.          
  461.       register unsigned short cPosition;
  462.       register unsigned short leftBounds, rightBounds;
  463.       register ColorSpec *theCSpecArray;
  464.       
  465.       if (!colorTableIsIndexed(tablePtr)) {
  466.          if (wEntry <= tablePtr->ctSize) {
  467.             *thePosition = wEntry;
  468.             return TRUE;
  469.          } else {
  470.             *thePosition = tablePtr->ctSize;
  471.             return FALSE;
  472.          }
  473.       }
  474.       
  475.       assertColorTableIsSorted(tablePtr);
  476.       
  477.       theCSpecArray = tablePtr->ctTable;
  478.       leftBounds = 0;  rightBounds = tablePtr->ctSize + 1 - 1;
  479.       cPosition = rightBounds / 2;
  480.       
  481.       while (leftBounds < rightBounds) {
  482.          
  483.          if (theCSpecArray[cPosition].value == wEntry) {
  484.             *thePosition = cPosition;
  485.             return TRUE;
  486.          } else {
  487.             if (theCSpecArray[cPosition].value < wEntry) {
  488.                leftBounds = cPosition;
  489.                cPosition += rightBounds + 1;
  490.                cPosition >>= 1;
  491.             } else {
  492.                rightBounds = cPosition;
  493.                cPosition += leftBounds;
  494.                cPosition >>= 1;
  495.             }
  496.          }
  497.          
  498.       }
  499.       
  500.          /*
  501.           * If the requested entry is not there, we want the entry that's
  502.           * right _after_ where it would go.
  503.           */
  504.          
  505.       if (theCSpecArray[cPosition].value < wEntry) {
  506.          ++cPosition;
  507.       }
  508.       
  509.       ASSERT(cPosition == tablePtr->ctSize+1 || theCSpecArray[cPosition].value > wEntry);
  510.       ASSERT(cPosition == 0 || theCSpecArray[cPosition-1].value < wEntry);
  511.       
  512.       *thePosition = cPosition;
  513.       return FALSE;
  514.    }
  515.    
  516.    
  517. short findEntryInSortedTable(CTabPtr theTable, short wEntry)
  518. {
  519.    short thePosition;
  520.    
  521.    if (engineFindEntryInSortedTable(theTable, wEntry, &thePosition)) {
  522.       return thePosition;
  523.    } else {
  524.       return kNoEntryFound;
  525.    }
  526. }
  527.  
  528.  
  529.  
  530. Boolean addEntryToSortedIndexedTable(CTabHandle theIndexedTable, ColorSpec *theColorSpec)
  531. {
  532.    register CTabPtr theIndexedTabPtr;
  533.    short wEntry;
  534.    short thePosition;
  535.    
  536.    ASSERT( colorTableIsIndexed(*theIndexedTable) );
  537.    
  538.    wEntry = theColorSpec->value;
  539.    
  540.    theIndexedTabPtr = *theIndexedTable;
  541.    if (engineFindEntryInSortedTable(theIndexedTabPtr, wEntry, &thePosition)) {
  542.       
  543.          /* No need to add the entry, it's already there. */
  544.       
  545.       theIndexedTabPtr->ctTable[thePosition] = *theColorSpec;
  546.       
  547.       return FALSE;
  548.       
  549.    } else {
  550.       
  551.       long newSize;
  552.       
  553.       newSize = sizeof(ColorTable)
  554.          + sizeof(ColorSpec) * ( theIndexedTabPtr->ctSize + 1 );
  555.       SetHandleSize( (Handle) theIndexedTable, newSize );
  556.       theIndexedTabPtr = *theIndexedTable;
  557.       
  558.       BlockMove( &theIndexedTabPtr->ctTable[thePosition],
  559.          &theIndexedTabPtr->ctTable[thePosition]+1,
  560.          (theIndexedTabPtr->ctSize+1 - thePosition) * sizeof(ColorSpec) );
  561.       
  562.       theIndexedTabPtr->ctTable[thePosition] = *theColorSpec;
  563.       
  564.       return TRUE;
  565.       
  566.    }
  567. }
  568.  
  569.  
  570.  
  571. CTabHandle makeIndexedFromSequential(CTabHandle theSequentialTable)
  572. {
  573.    CTabHandle theIndexedTable;
  574.    register ColorSpec *theSequentialColorSpecPtr;
  575.    register ColorSpec *theIndexedColorSpecPtr;
  576.    register CTabPtr theSequentialTablePtr;
  577.    register CTabPtr theIndexedTablePtr;
  578.    register short cIndexedEntry;
  579.    register short nSequentialEntriesMinusOne;
  580.    
  581.    ASSERT(theSequentialTable != NULL);
  582.    ASSERT(colorTableIsSequential(*theSequentialTable));
  583.    
  584.    nSequentialEntriesMinusOne = (**theSequentialTable).ctSize;
  585.    
  586.    theIndexedTable = (CTabHandle) NewHandle( sizeof(ColorTable)
  587.       + sizeof(ColorSpec) * nSequentialEntriesMinusOne );
  588.    theIndexedTablePtr = *theIndexedTable;
  589.    theSequentialTablePtr = *theSequentialTable;
  590.    
  591.    theIndexedTablePtr->ctSeed = theSequentialTablePtr->ctSeed;
  592.    theIndexedTablePtr->ctFlags = theSequentialTablePtr->ctFlags
  593.       & 0x3FFF
  594.       | 0x0000;
  595.    theIndexedTablePtr->ctSize = nSequentialEntriesMinusOne;
  596.    theIndexedColorSpecPtr = &theIndexedTablePtr->ctTable[0];
  597.    theSequentialColorSpecPtr = &theSequentialTablePtr->ctTable[0];
  598.    
  599.    for (cIndexedEntry = 0;
  600.       cIndexedEntry <= nSequentialEntriesMinusOne;
  601.       ++cIndexedEntry) {
  602.       
  603.       theIndexedColorSpecPtr->value = cIndexedEntry;
  604.       (theIndexedColorSpecPtr++)->rgb = (theSequentialColorSpecPtr++)->rgb;
  605.       
  606.    }
  607.    
  608.    return theIndexedTable;
  609. }
  610.  
  611.  
  612.  
  613. CTabHandle makeSequentialFromSortedIndexed(CTabHandle theIndexedTable, RGBColor *fillColor)
  614. {
  615.    CTabHandle theSequentialTable;
  616.    register ColorSpec *theIndexedColorSpecPtr;
  617.    register ColorSpec *theSequentialColorSpecPtr;
  618.    register CTabPtr theIndexedTablePtr;
  619.    register CTabPtr theSequentialTablePtr;
  620.    register short cSequentialEntry, nextIndexedEntry, nextIndexedPosition;
  621.    register short nIndexedEntriesMinusOne, nSequentialEntriesMinusOne;
  622.    
  623.    ASSERT(theIndexedTable != NULL);
  624.    ASSERT(colorTableIsIndexed(*theIndexedTable));
  625.    assertColorTableIsSorted(*theIndexedTable);
  626.    
  627.    nIndexedEntriesMinusOne = (**theIndexedTable).ctSize;
  628.    nSequentialEntriesMinusOne =
  629.       (**theIndexedTable).ctTable[nIndexedEntriesMinusOne].value;
  630.    
  631.    theSequentialTable = (CTabHandle) NewHandle( sizeof(ColorTable)
  632.       + sizeof(ColorSpec) * nSequentialEntriesMinusOne );
  633.    theSequentialTablePtr = *theSequentialTable;
  634.    theIndexedTablePtr = *theIndexedTable;
  635.    
  636.    theSequentialTablePtr->ctSeed = theIndexedTablePtr->ctSeed;
  637.    theSequentialTablePtr->ctFlags = theIndexedTablePtr->ctFlags
  638.       & 0x3FFF
  639.       | 0x8000;
  640.    theSequentialTablePtr->ctSize = nSequentialEntriesMinusOne;
  641.    theSequentialColorSpecPtr = &theSequentialTablePtr->ctTable[0];
  642.    theIndexedColorSpecPtr = &theIndexedTablePtr->ctTable[0];
  643.    
  644.    nextIndexedPosition = 0;
  645.    nextIndexedEntry = theIndexedColorSpecPtr[0].value;
  646.    for (cSequentialEntry = 0;
  647.       cSequentialEntry <= nSequentialEntriesMinusOne;
  648.       ++cSequentialEntry) {
  649.       
  650.       ASSERT(cSequentialEntry <= nextIndexedEntry);
  651.       
  652.       if (cSequentialEntry == nextIndexedEntry) {
  653.          theSequentialColorSpecPtr->value = cSequentialEntry;
  654.          (theSequentialColorSpecPtr++)->rgb = (theIndexedColorSpecPtr++)->rgb;
  655.          if (++nextIndexedPosition > nIndexedEntriesMinusOne) {
  656.             nextIndexedEntry = MAXINT;
  657.          } else {
  658.             nextIndexedEntry = theIndexedColorSpecPtr->value;
  659.          }
  660.       } else {
  661.          theSequentialColorSpecPtr->value = 0;
  662.          (theSequentialColorSpecPtr++)->rgb = *fillColor;
  663.       }
  664.       
  665.    }
  666.    
  667.    return theSequentialTable;
  668. }
  669.  
  670.  
  671.  
  672.    static int compareColorSpecValues(const ColorSpec *color1, const ColorSpec *color2);
  673.    static int compareColorSpecValues(register const ColorSpec *color1,
  674.       register const ColorSpec *color2)
  675.    {
  676.       if (color1->value != color2->value) {
  677.          if (color1->value < color2->value) {
  678.             return -1; 
  679.          } else {
  680.             return 1;
  681.          }
  682.       }
  683.       return 0;
  684.    }
  685.    
  686. void sortIndexedTable(CTabHandle theTable)
  687. {
  688.    register CTabPtr theTablePtr;
  689.    short oldState;
  690.    
  691.    ASSERT(theTable != NULL);
  692.    
  693.    theTablePtr = *theTable;
  694.    if (!colorTableIsIndexed(theTablePtr)) {
  695.       return ;
  696.    }
  697.    
  698.    oldState = HGetState( (Handle) theTable );
  699.    HLock( (Handle) theTable);
  700.    qsort( &theTablePtr->ctTable[0],
  701.       theTablePtr->ctSize+1,
  702.       sizeof(ColorSpec),
  703.       (__cmp_func) compareColorSpecValues);
  704.    HSetState( (Handle) theTable, oldState );
  705.    
  706.    assertColorTableIsSorted(theTablePtr);
  707. }
  708.  
  709.  
  710.  
  711. Boolean colorTablesAreEquivalent(CTabHandle table1, CTabHandle table2, RGBColor *fillColor)
  712. {
  713.    Boolean areEquivalent;
  714.    
  715.    ASSERT(table1 != NULL);
  716.    ASSERT(table2 != NULL);
  717.    
  718.    areEquivalent = TRUE;
  719.    
  720.    if (colorTableIsPaletted(*table1) || colorTableIsPaletted(*table2)) {
  721.          /* Paletted tables can't be compared to anything. */
  722.       return FALSE;
  723.    }
  724.    
  725.    if (colorTableIsSequential(*table1) || colorTableIsSequential(*table2)) {
  726.       
  727.          /*
  728.           * Convert one of the tables to sequential, if need be, and compare.
  729.           */
  730.       
  731.       register CTabPtr t1, t2;
  732.       register short nEntriesMinusOne;
  733.       CTabHandle convertedTable;
  734.       
  735.       convertedTable = NULL;
  736.       if (colorTableIsIndexed(*table1)) {
  737.          assertColorTableIsSorted(*table1);
  738.          convertedTable = makeSequentialFromSortedIndexed(table1, fillColor);
  739.          t1 = *convertedTable;
  740.          t2 = *table2;
  741.       } else if (colorTableIsIndexed(*table2)) {
  742.          assertColorTableIsSorted(*table2);
  743.          convertedTable = makeSequentialFromSortedIndexed(table2, fillColor);
  744.          t1 = *table1;
  745.          t2 = *convertedTable;
  746.       }
  747.       
  748.       if ( (nEntriesMinusOne=t1->ctSize) != t2->ctSize) {
  749.          
  750.          areEquivalent = FALSE;
  751.          
  752.       } else {
  753.          
  754.          register short cEntry;
  755.          
  756.          for (cEntry = 0; cEntry <= nEntriesMinusOne; ++cEntry) {
  757.             
  758.                /*
  759.                 * When comparing sequential tables, ignore the value field.
  760.                 */
  761.                
  762.             if ( t1->ctTable[cEntry].rgb.red != t2->ctTable[cEntry].rgb.red
  763.                || t1->ctTable[cEntry].rgb.green != t2->ctTable[cEntry].rgb.green
  764.                || t1->ctTable[cEntry].rgb.blue != t2->ctTable[cEntry].rgb.blue ) {
  765.                
  766.                areEquivalent = FALSE;
  767.                break;
  768.                
  769.             }
  770.             
  771.          }
  772.          
  773.       }
  774.       
  775.       DisposHandle( (Handle) convertedTable );
  776.       
  777.    } else {
  778.       
  779.          /*
  780.           * Leave both tables indexed, and compare.  Assume they're sorted.
  781.           */
  782.       
  783.       register CTabPtr t1, t2;
  784.       register short nEntriesMinusOne;
  785.       
  786.       t1 = *table1;
  787.       t2 = *table2;
  788.       
  789.       assertColorTableIsSorted(t1);
  790.       assertColorTableIsSorted(t2);
  791.       
  792.       if ( (nEntriesMinusOne=t1->ctSize) != t2->ctSize) {
  793.          
  794.          areEquivalent = FALSE;
  795.          
  796.       } else {
  797.          
  798.          register short cEntry;
  799.          
  800.          areEquivalent = ( jmemcmp(       // jmemcmp() is just a memcmp() clone
  801.             &t1->ctTable[0],
  802.             &t2->ctTable[0],
  803.             sizeof(ColorSpec)*(nEntriesMinusOne+1)
  804.             ) == 0);
  805.          
  806. #if you_want_it_spelled_out_for_you
  807.          for (cEntry = 0; cEntry <= nEntriesMinusOne; ++cEntry) {
  808.             if ( t1->ctTable[cEntry].value != t2->ctTable[cEntry].value
  809.                || t1->ctTable[cEntry].rgb.red != t2->ctTable[cEntry].rgb.red
  810.                || t1->ctTable[cEntry].rgb.green != t2->ctTable[cEntry].rgb.green
  811.                || t1->ctTable[cEntry].rgb.blue != t2->ctTable[cEntry].rgb.blue ) {
  812.                areEquivalent = FALSE;
  813.                break;
  814.             }
  815.          }
  816. #endif
  817.          
  818.       }
  819.       
  820.    }
  821.    
  822.    return areEquivalent;
  823. }
  824.  
  825.  
  826.  
  827. short (getNCTEntries)(CTabPtr theTable)
  828. {
  829.    return theTable->ctSize + 1;
  830. }
  831.  
  832.  
  833.  
  834. void setNCTEntries(CTabHandle theTable, short nEntries)
  835. {
  836.    short oldState;
  837.    
  838.    ASSERT(nEntries >= 0);
  839.    ASSERT(nEntries <= 256); // arbitrary
  840.    
  841.    if (getNCTEntries(*theTable) == nEntries) return;
  842.    
  843.    (**theTable).ctSize = nEntries-1;
  844.    
  845.    oldState = HGetState( (Handle) theTable );
  846.    HUnlock( (Handle) theTable );
  847.    SetHandleSize( (Handle) theTable,
  848.       sizeof(ColorTable) + (nEntries-1)*sizeof(ColorSpec));
  849.    HSetState( (Handle) theTable, oldState);
  850. }
  851.  
  852.  
  853.  
  854. void changeNCTEntries(CTabHandle theTable, short nEntries)
  855. {
  856.    if (nEntries == 0) return;
  857.    
  858.    setNCTEntries(theTable, getNCTEntries(*theTable) + nEntries);
  859. }
  860.  
  861.  
  862.  
  863. void (convertDepthToMaxNEntries)(short d, short n)
  864. {
  865.    DebugStr("\pconvertDepthToMaxNEntries was somehow called!");
  866. }
  867.  
  868.  
  869.  
  870. void (convertNEntriesToMinDepth)(short n, short d)
  871. {
  872.    DebugStr("\pconvertNEntriesToMinDepth was somehow called!");
  873. }
  874.  
  875. +++++++++++++++++++++++++++
  876.  
  877. From: k044477@hobbes.kzoo.edu (Jamie R. McCarthy)
  878. Organization: Kalamazoo College
  879. Date: Fri, 4 Sep 1992 20:49:09 GMT
  880.  
  881. k044477@hobbes.kzoo.edu (Jamie R. McCarthy) writes:
  882. >This article starts off with some AppleLink mail from Forrest Tanaka,
  883. >telling you more than you ever wanted to know about color tables, and
  884. >ends with a fair amount of ANSI C source code for manipulating them.
  885.  
  886. I've already (sigh) found several bugs in my code.  If you want an
  887. updated version, email me.
  888. - -- 
  889.  Jamie McCarthy      Internet: k044477@kzoo.edu      AppleLink: j.mccarthy
  890.  The same people who love MS-DOS so much that they went to PC Expo,
  891.  supported Ross Perot by an overwhelming margin.  This should be
  892.  telling you something.
  893.  
  894. ---------------------------
  895.  
  896. From: neath@brazil.psych.purdue.edu (Ian Neath)
  897. Subject: Keeping the cursor visible
  898. Date: 1 Sep 92 15:15:44 GMT
  899. Organization: Purdue University
  900.  
  901. I have an application that cranks through a simulation model.  Typically,
  902. it takes around an hour to do each run.  I have set up an animated cursor
  903. to let me know the program is still cranking, but everytime the app
  904. writes to the TextEdit record, the cursor is hidden by (I assume) a
  905. call to ObscureCursor.  Is it OK to keep calling ShowCursor to get
  906. my animated cursor back?  IM says to balance ShowCursor with Hide-
  907. or ShieldCursor (or vice versa).  My app seems to run fine, but since
  908. it takes so long to do each run, I don't want the program to bomb.
  909. Any advice, hints, etc appreciated.  Thanks.
  910.  
  911. - -ian
  912.  
  913. - --
  914.     Ian Neath, PhD     | There are four kinds of people in this world:
  915. neath@psych.purdue.edu | cretins, fools, morons and lunatics - U. Eco
  916.  
  917. +++++++++++++++++++++++++++
  918.  
  919. From: wombat@claris.com (Scott Lindsey)
  920. Date: 2 Sep 92 01:14:13 GMT
  921. Organization: Claris Corporation, Vancouver WA
  922.  
  923. In article <Btwnq8.LMv@mentor.cc.purdue.edu>, neath@brazil.psych.purdue.edu (Ian Neath) writes:
  924. > writes to the TextEdit record, the cursor is hidden by (I assume) a
  925. > call to ObscureCursor.  Is it OK to keep calling ShowCursor ...
  926.  
  927. ShowCursor won't actually show the cursor if it's only obscured.  I don't
  928. think there's a legal way to unobscure a cursor, however, setting the low-
  929. memory global CrsrNew = 0xFF forces it to really redraw. (CrsrNew is 0x8CE and
  930. is a 1-byte value).
  931.  
  932. - --
  933. Scott Lindsey <wombat@claris.com>
  934.  
  935. +++++++++++++++++++++++++++
  936.  
  937. From: d88-jwa@dront.nada.kth.se (Jon W{tte)
  938. Date: 2 Sep 92 12:33:30 GMT
  939. Organization: Royal Institute of Technology, Stockholm, Sweden
  940.  
  941. @claris.com (Scott Lindsey) writes:
  942.  
  943.    ShowCursor won't actually show the cursor if it's only obscured.  I don't
  944.    think there's a legal way to unobscure a cursor, however, setting the low-
  945.    memory global CrsrNew = 0xFF forces it to really redraw. (CrsrNew is 0x8CE
  946.    and is a 1-byte value).
  947.  
  948. How abotu just calling InitCursor?
  949.  
  950. It sets the cursor to an arrow, and shows it (and clears
  951. the show/hide count) and then you can call SetCursor to
  952. set it to the shape you want.
  953.  
  954. - -- 
  955. Jon W{tte, h+@nada.kth.se, Sweden, Phone +46-8-107069
  956. White, Literate, Employed, Higher-Educated, Male, Straight and Not Poor.
  957. I must be a bad guy.
  958.  
  959. +++++++++++++++++++++++++++
  960.  
  961. From: lari@strauss.cs.unc.edu (Humayun Lari)
  962. Date: 2 Sep 92 21:54:21 GMT
  963. Organization: The University of North Carolina at Chapel Hill
  964.  
  965. In article <15119@claris.com> wombat@claris.com (Scott Lindsey) writes:
  966. >In article <Btwnq8.LMv@mentor.cc.purdue.edu>, neath@brazil.psych.purdue.edu (Ian Neath) writes:
  967. >> 
  968. >> writes to the TextEdit record, the cursor is hidden by (I assume) a
  969. >> call to ObscureCursor.  Is it OK to keep calling ShowCursor ...
  970. >
  971. >ShowCursor won't actually show the cursor if it's only obscured.  I don't
  972. >think there's a legal way to unobscure a cursor, however, setting the low-
  973. >memory global CrsrNew = 0xFF forces it to really redraw.
  974.  
  975. If you're in charge of the writes to the TextEdit record (i.e. using TEKey),
  976. you could use TEInsert instead to prevent TextEdit from trying to be polite
  977. and calling ObscureCursor. Of course, TEInsert may be a bit slower, but in
  978. practice it seems to make little difference. And it's definitely *much* cleaner
  979. than having the cursor flicker every time a character is appended to the TE
  980. record (especially if you're porting a MS-DOS-based language interpreter that
  981. thinks a row of dots on the screen is a beautiful depiction of its progress).
  982.  
  983. Humayun Lari
  984. (lari@cs.unc.edu)
  985.  
  986. +++++++++++++++++++++++++++
  987.  
  988. From: wombat@claris.com (Scott Lindsey)
  989. Date: 4 Sep 92 23:44:50 GMT
  990. Organization: Claris Corporation, Vancouver WA
  991.  
  992. In article <D88-JWA.92Sep2133330@dront.nada.kth.se>, d88-jwa@dront.nada.kth.se (Jon W{tte) writes:
  993. > @claris.com (Scott Lindsey) writes:
  994. >    ShowCursor won't actually show the cursor if it's only obscured.  I don't
  995. >    think there's a legal way to unobscure a cursor, however, setting the low-
  996. >    memory global CrsrNew = 0xFF forces it to really redraw. (CrsrNew is 0x8CE
  997. >    and is a 1-byte value).
  998. > How abotu just calling InitCursor?
  999. > It sets the cursor to an arrow, and shows it (and clears
  1000. > the show/hide count) and then you can call SetCursor to
  1001. > set it to the shape you want.
  1002.  
  1003. I've lost the original message, but I think the issue was a progress cursor
  1004. (beachball or something).  In fact, in ClarisWorks, I use CrsrNew to show the
  1005. cursor whenever the beachball comes up, just in case the cursor was obscured.
  1006. That way, you won't be sitting there with an obscured spinning beachball.
  1007.  
  1008. - --
  1009. Scott Lindsey <wombat@claris.com>
  1010.  
  1011. ---------------------------
  1012.  
  1013. From: Ray.Arachelian@f204.n2603.z1.ieee.org (Ray Arachelian)
  1014. Subject: Zbasic+System 6/7 Speed
  1015. Organization: FidoNet node 1:2603/204 - Not Even Odd, Forest Hills NY
  1016. Date: Sat, 22 Aug 1992 20:25:01 GMT
  1017.  
  1018. Most of you won't be familiar with Zedcor's Zbasic.  A fine BASIC 
  1019. compiler, but perhaps you could throw in some hints about performance 
  1020. problems with System 7 which didn't exist under System 6.
  1021.  
  1022. After a few months of System 7 use, I did install System 6.0.7 on a 
  1023. Syquest cartridge so that I'd be able to test some software I'd written 
  1024. with Zedcor's ZBasic with System 6, to make sure I didn't put in any 
  1025. inadvertent incompatibilities (of which I did find one and fix it.)
  1026.  
  1027. I saw that the program ran about 3 times faster than under System 7!  What 
  1028. exactly gets a program that was compiled with ZBasic that slow down so 
  1029. much in System 7 yet run so well under 6?
  1030.  
  1031. Currently I had to implement double buffering of the modem and keyboard in 
  1032. order to get better performance.  I'm running this on a IIcx which by no 
  1033. means is a slow machine.  No a Quadra, but still faster than a Plus no 
  1034. less.
  1035.  
  1036. Having called Zedcor, I've been told they're "never" going to release 
  1037. ZBasic 6.0.  It will be called something like "Future" basic, and just as 
  1038. the last month's call confirmed their oppinion, "it will be available next 
  1039. month." :-)
  1040.  
  1041. Is there something ZBasic does wrong in terms of WaitNextEvent or 
  1042. GetNextEvent?  Certainly with ZBasic you have almost no control over these 
  1043. commands, as it does it's own event handling to buffer you away from the 
  1044. tool box.  This is good for new programmers, but gets very cumbersome with 
  1045. me.
  1046.  
  1047. How about the text writing routines (not TEdit routines, quickdraw text 
  1048. printing routines.)  Have they been slowed down in System 7 with TType?
  1049.  
  1050. I'm trying to track down the problem and perhaps lessen its effects if not 
  1051. remove it.  Another thing I notice is that if I have any INIT's or CDEVs 
  1052. that grab the keyboard (QuickKeys, etc) the program slows down to hell.  
  1053. I'm grabbing keystrokes via system events (IE: DIALOG(16) function in 
  1054. ZBasic.)
  1055.  
  1056. I'd hate to do so, but if I must I'll go in there with ResEdit and force 
  1057. Zbasic to produce the proper calls to WaitNextEvent with less of a delay 
  1058. time slice give up.  Without doubt, I don't want to force my (potential) 
  1059. users to run this software under System 6.0.x :-)
  1060.  
  1061. Any ideas would be greatly appreciated.
  1062.  
  1063.  * Freddie 1.3b2 * Do what thou whim shalt be a hole in the head!
  1064.  
  1065. - --  
  1066. =*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
  1067.  Ray Arachelian - Internet: Ray.Arachelian@f204.n2603.z1.ieee.org
  1068.  
  1069. +++++++++++++++++++++++++++
  1070.  
  1071. From: mxmora@unix.SRI.COM (Matt Mora)
  1072. Date: 25 Aug 92 16:03:14 GMT
  1073. Organization: SRI International, Menlo Park, California
  1074.  
  1075. In article <15639.2A996B26@zeus.ieee.org> Ray.Arachelian@f204.n2603.z1.ieee.org (Ray Arachelian) writes:
  1076.  
  1077. >Is there something ZBasic does wrong in terms of WaitNextEvent or 
  1078. >GetNextEvent?  Certainly with ZBasic you have almost no control over these 
  1079. >commands, as it does it's own event handling to buffer you away from the 
  1080. >tool box.  This is good for new programmers, but gets very cumbersome with 
  1081. >me.
  1082.  
  1083. Yes it calls WNE/GNE before every line of your basic code. Not very
  1084. efficient. Don't worry about it.  Wait for future basic and
  1085. upgrade as soon as you can.
  1086.  
  1087.  
  1088.  
  1089. Matt
  1090.  
  1091. - -- 
  1092. ___________________________________________________________
  1093. Matthew Mora                |   my Mac  Matt_Mora@sri.com
  1094. SRI International           |  my unix  mxmora@unix.sri.com
  1095. ___________________________________________________________
  1096.  
  1097. +++++++++++++++++++++++++++
  1098.  
  1099. From: Ray.Arachelian@f204.n2603.z1.ieee.org (Ray Arachelian)
  1100. Date: 30 Aug 92 20:30:07 GMT
  1101. Organization: FidoNet node 1:2603/204 - Not Even Odd, Forest Hills NY
  1102.  
  1103. On 08-25-92, MXMORA@UNIX.SRI.COM wrote to ALL:
  1104.  
  1105.  M> Yes it calls WNE/GNE before every line of your basic code. Not very 
  1106.  M> efficient. Don't worry about it.  Wait for future basic and upgrade 
  1107.  M> as soon as you can. 
  1108.  
  1109. I do plan to get Future Basic, however, I've no intention of waiting 
  1110. around every time they tell me "Next Month" :-)  I did find out what they 
  1111. do wrong.  They not only call _GetNextEvent on every line, but they also 
  1112. make a LOT of calls to _SystemTask.  I've even found a timing routine 
  1113. where they check the timer, and call _SystemTask over and over again.  
  1114. This really slows things down under System 7....  I've also tried to 
  1115. replace this with a call to WaitNextEvent, however, all I've managed to do 
  1116. was crash the machine. :-)  See my other messages about patching...
  1117.  
  1118.  
  1119.  * Freddie 1.3b2 * Do what thou whim shalt be a hole in the head!
  1120.  
  1121. - --  
  1122. =*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
  1123.  Ray Arachelian - Internet: Ray.Arachelian@f204.n2603.z1.ieee.org
  1124.  
  1125. +++++++++++++++++++++++++++
  1126.  
  1127. From: Glen.Stewart@f175.n2240.z1.ieee.org (Glen Stewart)
  1128. Date: 25 Aug 92 14:21:24 GMT
  1129. Organization: FidoNet node 1:2240/175 - The Associati, Grand Blanc MI
  1130.  
  1131. Zedcor may have led you astray.  I've been calling them on and off for the
  1132. past 6 months.  They have always told me that they ARE doing Zbasic 6.0!
  1133.  
  1134. In fact, they told me late last week, that they have sent the upgrade notices
  1135. to all the old users, and that 6.0 is now basically complete.
  1136.  
  1137. Look forward to increased support for HyperCard externals!
  1138.  
  1139.  
  1140. - --  
  1141. =*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
  1142.  Glen Stewart - Internet: Glen.Stewart@f175.n2240.z1.ieee.org
  1143.  
  1144. +++++++++++++++++++++++++++
  1145.  
  1146. From: Ray.Arachelian@f204.n2603.z1.ieee.org (Ray Arachelian)
  1147. Date: 2 Sep 92 20:42:01 GMT
  1148. Organization: FidoNet node 1:2603/204 - Not Even Odd, Forest Hills NY
  1149.  
  1150. Generally, when I've called Zedcor, a female voice answered and told me "Not
  1151.  
  1152. Yet."  The "Future Basic" rumor as it may be was by a male voice.  This was
  1153.  
  1154. when I called on the weekend, so I assumed it was perhaps one of their long
  1155.  
  1156. hour programmers.
  1157.  
  1158. However the deadline seems to have lessened.  Yesterday's call told me
  1159. "Middle
  1160.  of this month" instead of "Next Month" so things are indeed getting
  1161. better :-)
  1162.  
  1163.  
  1164. - --  
  1165. =*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
  1166.  Ray Arachelian - Internet: Ray.Arachelian@f204.n2603.z1.ieee.org
  1167.  
  1168. ---------------------------
  1169.  
  1170. From: mcnichol@terminator.psy.syr.edu (Brendan T. McNichols)
  1171. Subject: Function missing from MPW C library?
  1172. Date: Thu, 23 Jul 92 13:27:49 EDT
  1173.  
  1174.  
  1175. Hi all,
  1176.  
  1177. I am getting the following error message when building a project using  
  1178. MPW C:
  1179.  
  1180. ### Link: Error: Undefined entry, name: (Error 28) "str2dec"
  1181.   Referenced from: _doscan in file: Alliance Drive  
  1182. :Development:MPW:Libraries:CLibraries:CLib881.o
  1183. ### Link: Errors prevented normal completion.
  1184. ### MPW Shell - Execution of KLSyn88.makeout terminated.
  1185. ### MPW Shell - Execution of BuildProgram terminated.
  1186.  
  1187. It seems to me that this means that the function "str2dec" is missing  
  1188. from the CSANELib881.o library.  (It is declared in SANE.h.)  I am new  
  1189. using MPW and I'm not sure if there's something here that I should have  
  1190. done but didn't.  Does anyone know how to fix this problem?  Is str2dec  
  1191. located in some other library?  Can I get the code for str2dec and  
  1192. include it in the CSANELib881.o library?
  1193.  
  1194. Thanks very much for any help,
  1195. Brendan 
  1196.  
  1197. - --
  1198. Brendan T. McNichols, Computer Support                (315) 443-9902
  1199. Psyracuse U. Sychology Dept.             mcnichol@psy.syr.edu (NeXT)
  1200. 430 Huntington Hall                                 mcnichol@syr.edu
  1201. Syracuse, NY 13244
  1202.  
  1203. +++++++++++++++++++++++++++
  1204.  
  1205. From: keith@taligent.com (Keith Rollin)
  1206. Date: 24 Jul 92 19:38:37 GMT
  1207. Organization: Taligent
  1208.  
  1209. In article <1992Jul23.132750.12392@newstand.syr.edu>,
  1210. mcnichol@terminator.psy.syr.edu (Brendan T. McNichols) writes:
  1211. > I am getting the following error message when building a project using  
  1212. > MPW C:
  1213. > ### Link: Error: Undefined entry, name: (Error 28) "str2dec"
  1214. >   Referenced from: _doscan in file: Alliance Drive  
  1215. > :Development:MPW:Libraries:CLibraries:CLib881.o
  1216. > ### Link: Errors prevented normal completion.
  1217. > ### MPW Shell - Execution of KLSyn88.makeout terminated.
  1218. > ### MPW Shell - Execution of BuildProgram terminated.
  1219. > It seems to me that this means that the function "str2dec" is missing  
  1220. > from the CSANELib881.o library.  (It is declared in SANE.h.)  I am new  
  1221. > using MPW and I'm not sure if there's something here that I should have  
  1222. > done but didn't.  Does anyone know how to fix this problem?  Is str2dec  
  1223. > located in some other library?  Can I get the code for str2dec and  
  1224. > include it in the CSANELib881.o library?
  1225.  
  1226. There seem to b versions of str2dec in {Libraries}Runtime.o and
  1227. {PLIbraries}PasLib.o. Whenever I have problems finding a library routine, I use
  1228. the following script.
  1229.  
  1230. Set Exit 0
  1231. Set SearchExpression "`Request "Enter regular expression" || Echo '""'`"
  1232. Exit if "{SearchExpression}" == ""
  1233. For folder in "{Libraries}" "{PLibraries}" "{CLibraries}"
  1234.     Echo "Searching in {folder}"
  1235.     For file In `files -f -s -t "OBJ " "{folder}"`
  1236.         DumpObj -mods "{file}" | Search -nf /{SearchExpression}/ opt-3opt3 Dev:Null
  1237.         If {status} == 0
  1238.             Echo "DumpObj opt-d"{file}opt-d" -m {SearchExpression}"
  1239.         End
  1240.     End
  1241. End opt-wopt-w "{WorkSheet}"
  1242. Set Exit 1
  1243.  
  1244.  
  1245. - --
  1246. Keith Rollin
  1247. Phantom Programmer
  1248. Taligent, Inc.
  1249.  
  1250. ---------------------------
  1251.  
  1252. End of C.S.M.P. Digest
  1253. **********************
  1254.